package com.sczmgk.hotline_pzh.base;

import android.os.Message;

import com.google.gson.Gson;
import com.sczmgk.hotline_pzh.callback.HttpFailCallback;
import com.sczmgk.hotline_pzh.callback.OnRefreshListener;
import com.sczmgk.hotline_pzh.callback.SimplePaserJsonCallback;
import com.sczmgk.hotline_pzh.dialog.DialogFactory;
import com.sczmgk.hotline_pzh.httputils.MyHttp;
import com.sczmgk.hotline_pzh.hxim.ChatMessageComparator;
import com.sczmgk.hotline_pzh.utils.MyLog;
import com.sczmgk.hotline_pzh.utils.MyToast;
import com.sczmgk.hotline_pzh.utils.Tools;
import com.sczmgk.hotline_pzh.view.RefreshListView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 通用List 上拉加载下拉刷新,有title
 *
 * @param <M>
 */
public abstract class RefreshAndLoadMoreBaseActivity<M> extends BaseActivity {


    protected final int LIST_TYPE_UP_LOAD_MORE = 1;
    /**
     * 下拉加载更多(list需要倒序)
     */
    protected final int LIST_TYPE_DOWN_LOAD_MORE = 2;
    protected RefreshListView mListView;
    protected final int REFRESH_LIST = 101;
    protected final int HIDE_FOOTER_HEADER = 102;
    protected List<M> lists = new ArrayList<M>();
    protected List<M> cacheLists = new ArrayList<M>();
    /**
     * 附加list
     */
    protected JSONArray extrasList;
    /**
     * 默认第一次加载
     */
    protected final int LOAD_NORMAL = 0;
    /**
     * 下拉刷新状态
     */
    protected final int PULL_REFRESH = 1;
    /**
     * 上拉加载更多
     */
    protected final int LOAD_MORE = 2;

    /**
     * 已加载的页数
     */
    protected int loadedPage;
    /**
     * 当前页
     */
    protected int nowpage;
    /**
     * 总页数
     */
    protected int totalpages;
    protected String systemtime;
    protected int count;
    protected String keyword = "";
    private ChatMessageComparator chatMessageComparator = new ChatMessageComparator();
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case REFRESH_LIST:
//                mListView.hideHeaderView();
                break;
            case HIDE_FOOTER_HEADER:
                mListView.hideFooterView();
                mListView.hideHeaderView();
                break;
            default:
                break;
        }
    }

    /**
     * @param dataRaw
     * @param loadType
     */
    protected void paserJson(String dataRaw, int loadType) {
        //取得字节码

        //这里要取得泛型的类型
        Class clazz = getJsonClazz();
//        MyLog.d(TAG,"取得泛型的类型是："+clazz);
        String c = clazz.getSimpleName();


        MyLog.d(TAG, "公共方法解析json的内容是 ：" + dataRaw);
        if (Tools.isEmpty(dataRaw)) {
            MyToast.showDebug(this, "json  error!");
            return;
        }

        JSONArray datalist = null;
        List<M> datas = new ArrayList<M>();
        try {
            //取到最外层字段
            JSONObject jsonObject = new JSONObject(dataRaw);
            nowpage = jsonObject.getInt("nowpage");
            totalpages = jsonObject.getInt("totalpages");

            try {
                count = jsonObject.getInt("count");
            } catch (JSONException e) {
                e.printStackTrace();
                MyLog.e(TAG, "count，解析错误");
            }
            systemtime = jsonObject.getString("systemtime");
            datalist = jsonObject.getJSONArray("datalist");
            // TODO 取出第二个list
            try {
                extrasList = jsonObject.getJSONArray("accountants");
            } catch (JSONException e) {
                e.printStackTrace();
                MyLog.e(TAG, "exteasList，解析错误");
            }
            //取得数组大小
            int len = datalist.length();
            for (int i = 0; i < len; i++) {
                //分别取出对像
                String data = datalist.get(i).toString();
                Gson gson = new Gson();
                M m = (M) gson.fromJson(data, clazz);
                datas.add(m);
            }
            MyLog.d(TAG, "lists   size() : " + datas.size());
        } catch (JSONException e) {
            e.printStackTrace();
            MyLog.e(TAG, "公用List josn   解析错误");
        }
        Gson gson = new Gson();
        //取出的已不是json字符串
        if (this.nowpage > loadedPage) { //缓存已加载的页数
            loadedPage = this.nowpage;
        }

        switch(loadType){
            case LOAD_MORE:
                MyLog.i(TAG, "加载更多的第：" + nowpage + "  页");
                int showPosition = datas.size()+1;

                if(getListType() == LIST_TYPE_DOWN_LOAD_MORE){

                    //缓存加入的信息
                    cacheLists = datas;
                    // 1.将原来的集合反转
                    Collections.reverse(lists);
                    // 2.加入新增的集合
                    lists.addAll(cacheLists);
                    // 3.再次排序
                    Collections.sort(lists, chatMessageComparator);

                    cacheLists.clear();
                }else{
                    lists.addAll(datas);
                }


                refreshList(nowpage == 1? -1 :showPosition);
                break;
            case LOAD_NORMAL:
            case PULL_REFRESH:
                if (nowpage == 1) {//加载的当前页是第一页
                    if (lists.size() > 0) {
                        MyLog.i(TAG, "初始化或下拉刷新的第一页，清空集合 ！");
                        lists.clear();
                    }
                }

                lists.addAll(datas);
                if(getListType() == LIST_TYPE_DOWN_LOAD_MORE){
                    Collections.sort(lists, chatMessageComparator);
                }
                refreshList(-1);
                break;
        }

        if(getListType() == LIST_TYPE_UP_LOAD_MORE){//显示底线
            if(nowpage == totalpages){
                mListView.showNotMore();
            }else{
                mListView.hideNotMore();
            }
        }

    }

    /**
     * 发消息更新list
     */
    protected void refreshList(int position) {
        Message msg = Message.obtain();
        msg.what = REFRESH_LIST;
        msg.obj = position;
        mHandler.sendMessage(msg);
    }

    /**
     * 加载数据
     *
     * @param page
     * @param loadStatus
     */
    protected void loadData(final int page, String keyoword, final int loadStatus) {
        if(mListView != null && loadStatus != LOAD_MORE){
            mListView.hideNotMore();
        }

        if (loadingDialog != null && loadingDialog.isShowing()) {

        }else{
            loadingDialog = (loadStatus == LOAD_NORMAL ? DialogFactory.getLoadingDialog(RefreshAndLoadMoreBaseActivity.this) : null);
            DialogFactory.showDialog(loadingDialog);
        }
        MyHttp.requestByFailCallback(getRquestUrl(), getRequestData(page, keyoword), MyHttp.GET, RefreshAndLoadMoreBaseActivity.this, false,null
                , new SimplePaserJsonCallback() {
                    @Override
                    public void onVerifyIsNull() {
                        DialogFactory.dismissLoadingDialog(loadingDialog);
                    }

                    @Override
                    public void onVerifySuccess(String dataRaw, boolean isCache) {
                        DialogFactory.dismissLoadingDialog(loadingDialog);
                        paserJson(dataRaw, loadStatus);

                        Message msg = Message.obtain();
                        msg.what = HIDE_FOOTER_HEADER;
                        mHandler.sendMessage(msg);
                    }
                }, new HttpFailCallback() {
                    @Override
                    public void onServiceErrorCallback() {
                        DialogFactory.dismissLoadingDialog(loadingDialog);
                        MyLog.e(TAG, "服务器错误！   ");
                        Message msg = Message.obtain();
                        msg.what = HIDE_FOOTER_HEADER;
                        mHandler.sendMessage(msg);
                    }
                });

    }

    /**
     * 设置监听
     */
    public void setListener() {
        mListView.setOnRefreshListener(new OnRefreshListener() {

            @Override
            public void onPullDownRefresh() {
                MyLog.i(TAG, "下拉刷新----");
                if(getListType() == LIST_TYPE_UP_LOAD_MORE){
                    loadData(1, keyword, PULL_REFRESH);
                }else{
                    MyLog.i(TAG, "totalpages:　" + totalpages + "      nowpages :" + nowpage);
                    if (totalpages > nowpage) {
                        loadData(nowpage + 1, keyword, LOAD_MORE);

                    } else {
                        Message msg = Message.obtain();
                        msg.what = HIDE_FOOTER_HEADER;
                        mHandler.sendMessage(msg);
//                        MyToast.show(RefreshAndLoadMoreBaseActivity.this, "没有更多数据！");
                    }
                }

            }

            @Override
            public void onLoadingMore() {
                if(getListType() == LIST_TYPE_UP_LOAD_MORE){
                    MyLog.i(TAG, "totalpages:　" + totalpages + "      nowpages :" + nowpage);
                    if (totalpages > nowpage) {
                        loadData(nowpage + 1, keyword, LOAD_MORE);

                    } else {
                       mListView.showNotMore();
                    }
                }else{

                    loadData(1, keyword, PULL_REFRESH);
                }

            }
        });

    }

    /**
     * 子类实现取得说请求maps
     *
     * @param page
     * @param keyword
     * @return
     */
    public abstract Map<String, Object> getRequestData(int page, String keyword);

    /**
     * 子类实现取得urL
     *
     * @return
     */
    public abstract String getRquestUrl();

    /**
     * 取得泛型的类型的字节码
     *
     * @return
     */
    public Class getJsonClazz() {
        //1.取得当前运行的clss（传入M 的类）
        Class clazz = getClass();
        //2.取得父类的类型（也就是本类）
        Type superclass = clazz.getGenericSuperclass();
        //3.判断本类是否支持泛型
        if (superclass instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) superclass).getActualTypeArguments();
            //取得第一个就是实际类型
            Type actualTypeArgument = actualTypeArguments[0];
            //强转成字节码
            Class c = (Class) actualTypeArgument;
            //得到实例
            return c;
        }
        return null;
    }
    public abstract int getListType();
}
